package com.moleq.mgnetwork;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import com.moleq.model.NetWorkSetting;
import com.moleq.service.NetWorkSettingService;

public class TransporterService extends Service {
	/**
	 * create handler object as thread pass to postDelayed
	 */

	private Context sharedContext = null;
	private NetWorkSettingService dbservice = null;
	private CommTaskParser xmlParser = new CommTaskParser();

	private static final String TAG = "MGService";
	private Handler objHandler = new Handler();
	private boolean isRunning = false;

	private int intCounter = 0;

	private FileHandler filehandler = null;
	private FolderMonitor folderMonitor = null;
	private DirMonitor dirMonitor = null;
	private FolderMonitor processor = null;
	private FolderMonitor analyzer = null;
	private CommTaskParser parser = new CommTaskParser();
	private FileProcessor fileProcessor = new FileProcessor();

	private FileChangeCallback dirFileCallback = new FileChangeCallback() {

		public void onProcessFiles(final Map<String, String> nowDirFileMap) {
			// TODO Auto-generated method stub
		}

		public void onProcessFiles(final File[] files) {

			for (File file : files) {
				System.out.println("->> dirFile file: " + file.getAbsoluteFile());
			}

			InitFolder();

			for (File file : files) {
				System.out.println("->> file: " + file.getAbsoluteFile());
			}

			new Thread() {

				@Override
				public void run() {
					String tmpIP = "";

					for (File file : files) {
						String fileName = "" + file.getAbsoluteFile();

						if (fileName.indexOf(".tmp") >= 0 || fileName.indexOf(".temp") >= 0)
							continue;

						if (fileName.indexOf(".xml") < 0)
							continue;

						try {
							CommTask task = parser.getCommTasks(fileName);
							tmpIP = task.getIpAddress();

							filehandler.sendFile(tmpIP, fileName);
							Thread.sleep(2000);

						} catch (Exception e) {
							// TODO: handle exception
						} catch (Throwable e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

					}

				}

			}.start();

		}
	};

	private Runnable mTasks = new Runnable() {
		public void run() {
			intCounter++;

			Log.i("MG-POS", "Counter:" + Integer.toString(intCounter));

			objHandler.postDelayed(mTasks, 1000);
		}
	};

	private FileChangeCallback processorFileCallback = new FileChangeCallback() {

		public void onProcessFiles(Map<String, String> nowDirFileMap) {
			// TODO Auto-generated method stub

		}

		public void onProcessFiles(final File[] files) {
			// TODO Auto-generated method stub
			for (File file : files) {
				System.out.println("->> processor file: " + file.getAbsoluteFile());
			}
			
			new Thread() {

				@Override
				public void run() {
					String tmpIP = "";

					for (File file : files) {
						String fileName = "" + file.getAbsoluteFile();

						if (fileName.indexOf(".xml") < 0)
							continue;

						try {
							CommTask task = parser.getCommTasks(fileName);
							
							fileProcessor.processCommTask(task);
//							NetWorkSetting setting = task.toNetworkSetting();
//							dbservice.InsertOrUpdate(setting);

							Thread.sleep(1000);

						} catch (Exception e) {
							// TODO: handle exception
						} catch (Throwable e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

					}

				}

			}.start();
			

		}

	};
	private FileChangeCallback analyzerFileCallback = new FileChangeCallback() {

		public void onProcessFiles(Map<String, String> nowDirFileMap) {
			// TODO Auto-generated method stub

		}

		public void onProcessFiles(final File[] files) {
			for (File file : files) {
				System.out.println("->> analyzer file: " + file.getAbsoluteFile());
			}

			new Thread() {

				@Override
				public void run() {
					String tmpIP = "";
					try {

						for (File file : files) {
							String fileName = "" + file.getAbsoluteFile();

							if (fileName.indexOf(".txt") < 0)
								continue;

							if (file.exists()) {
							
								// txt to xml
								List<NetWorkSetting> settings = dbservice.FindAll();

								if(settings.size() == 0) return;
								
								File newFile = new File(fileName + ".tmp");
								file.renameTo(newFile);
								
								String strNow = getNow();
								String xmlFileName = "";

								for (int i = 0; i < settings.size(); i++) {

									NetWorkSetting setting = settings.get(i);
									List<String> actions = fileProcessor.getActions(newFile);
									String strDBStruct = fileProcessor.getDatabaseStructure(newFile);
									xmlFileName = String.format(Constant.ANALYZED_XML_FILE_NAME, String.format("%02d",setting.getNs_station()), strNow);
									CommTask task = new CommTask();
									task.setStation(setting.getNs_station());
									task.setIpAddress(setting.getNs_ip());
									task.setCreateDateTime(strNow);
									task.setDbStructure(strDBStruct);
									task.setActions(actions);
									xmlParser.save(task, Constant.SDCARD_OUT_BOX + xmlFileName);

								}

								newFile.delete();
							}

						}

					} catch (Exception e) {
						// TODO: handle exception
					} catch (Throwable e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			}.start();

		}

	};

	public String getNow() {

		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmm");
		Date curDate = new Date(System.currentTimeMillis());// 閿熸枻鎷峰彇閿熸枻鎷峰墠鏃堕敓鏂ゆ嫹
		String str = formatter.format(curDate);

		return str;
	}

	private void doTaskJob() {

		filehandler = new FileHandler();
		filehandler.start();

		analyzer = new FolderMonitor(Constant.SDCARD_MGPOS_CACHE, 20, analyzerFileCallback);
		analyzer.start();

		// dirMonitor = new DirMonitor(Constant.SDCARD_OUT_BOX, 15,
		// dirFileCallback);
		// dirMonitor.start();

		processor = new FolderMonitor(Constant.SDCARD_IN_BOX, 10, processorFileCallback);
		processor.start();

		folderMonitor = new FolderMonitor(Constant.SDCARD_OUT_BOX, 15, dirFileCallback);
		folderMonitor.start();

	}

	private void InitFolder() {
		String inbox = Constant.SDCARD_IN_BOX;
		String outbox = Constant.SDCARD_OUT_BOX;
		String mgposCache = Constant.SDCARD_MGPOS_CACHE;

		File folder = new File(inbox);
		if (!folder.exists()) {
			folder.mkdirs();
			Log.i("LogDemo", "mkdir inbox folder ...");
		}

		folder = new File(outbox);
		if (!folder.exists()) {
			folder.mkdirs();
			Log.i("LogDemo", "mkdir outbox folder ...");
		}

		folder = new File(mgposCache);
		if (!folder.exists()) {
			folder.mkdirs();
			Log.i("LogDemo", "mkdir mgpos cache folder ...");
		}

	}

	private ServiceBroadcastReceiver receiver;
	private String shareDBPath;

	public void onCreate() {
		Log.d(TAG, "============> MGService.onCreate");
		// showNotification();
		super.onCreate();
	}

	public void onStart(Intent intent, int startId) {

		if (!isRunning) {

			 init();

			InitFolder();

			doTaskJob();

			Log.i(TAG, "============> MGService.onStart");
			// objHandler.postDelayed(mTasks, 1000);

			regBroadcastReceiver();

			isRunning = true;
		}

		super.onStart(intent, startId);
	}

	private void init() {

		try {
			sharedContext = this.createPackageContext(Constant.DB_PACKAGE_NAME, Context.CONTEXT_IGNORE_SECURITY);
			if (sharedContext == null) {
				return;
			}
		} catch (Exception e) {
			String error = e.getMessage();
			return;
		}

		shareDBPath = sharedContext.getDatabasePath(Constant.DATABASE_NAME).getAbsolutePath();

		dbservice = new NetWorkSettingService();
	}

	public IBinder onBind(Intent intent) {
		Log.i(TAG, "============> MGService.onBind");
		return null;
	}

	public class LocalBinder extends Binder {
		public TransporterService getService() {
			return TransporterService.this;
		}
	}

	public boolean onUnbind(Intent intent) {
		Log.i(TAG, "============> MGService.onUnbind");
		return false;
	}

	public void onRebind(Intent intent) {
		Log.i(TAG, "============> MGService.onRebind");
	}

	public void onDestroy() {

		if (isRunning) {
			unregisterReceiver(receiver);

			if (folderMonitor != null)
				folderMonitor.release();

			if (analyzer != null)
				analyzer.release();

			if (processor != null)
				processor.release();

			// if (dirMonitor != null)
			// dirMonitor.release();

			if (filehandler != null)
				filehandler.release();

			Log.i(TAG, "============> MGService.onDestroy");
			// objHandler.removeCallbacks(mTasks);
			isRunning = false;
		}
		super.onDestroy();

	}

	private void regBroadcastReceiver() {
		receiver = new ServiceBroadcastReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(Constant.startServiceAction);
		filter.addAction(Constant.stopServiceAction);
		registerReceiver(receiver, filter);
	}

	private class ServiceBroadcastReceiver extends BroadcastReceiver {

		private static final String TAG = "ServiceBroadcastReceiver";

		@Override
		public void onReceive(Context context, Intent intent) {

			if (intent.getAction().equals(Constant.startServiceAction)) {
				Log.i(TAG, "start service ...");
				Intent i = new Intent(context, TransporterService.class);
				context.startService(i);

			} else if (intent.getAction().equals(Constant.stopServiceAction)) {

				Log.i(TAG, "stop service ...");
				Intent i = new Intent(context, TransporterService.class);
				context.stopService(i);
			}
		}
	}

}